const fs = require('fs')
const Path = require('path')
const Join = Path.join
const _ = require('lodash')

function getJsonFiles(jsonPath) {
    let jsonFiles = [];

    function findJsonFile(path) {
        let files = fs.readdirSync(path);
        files.forEach(function (item, index) {
            let fPath = Join(path, item);
            let stat = fs.statSync(fPath);
            if (stat.isDirectory() === true) {
                findJsonFile(fPath);
            }
            if (stat.isFile() === true) {
                jsonFiles.push(fPath);
            }
        });
    }


    findJsonFile(jsonPath);

    return jsonFiles
}

const Routers = {}
export default async function (app, path = './src/controlller') {
    var filesNameArray = getJsonFiles(Path.resolve('./', './src/controller'))
    // console.log("filesNameArray====>", filesNameArray)
    filesNameArray.forEach(filesName => {
        const _Router = require(filesName).default;
        // const _router = new _Router()
        // console.log("router._type====>",router._type)
        // console.log(filesName + " router====>", _Router)
        // console.log("_Router====>", _Router)
        // console.log("_Router.prototype.reqList====>", _Router.prototype.reqList)
        if (_Router && _Router._type === "Controller") {
            _.map(_Router.prototype.reqList, (funs, key) => {
                var method = key.split(":")[0]
                var methodName = key.split(":")[1]
                if (method === 'del') {
                    method = "delete"
                }
                var url = key.split(":")[2]
                Routers[`${method}:${url}`] = {
                    controller: _Router,
                    methodName,
                    funs
                }
            })
        }

    })
    return async function (ctx, next) {
        let result = null;
        var ControllerAndFunc = Routers[`${ctx.req.method.toLowerCase()}:${ctx.url.split("?")[0]}`]
        var error = null
        if (ControllerAndFunc) {
            var controller = new ControllerAndFunc.controller(ctx, next)
            //排序 ControllerAndFunc.funs validate 排在最前面
            var validateFunc = ControllerAndFunc.funs.filter(item => item.validate)
            if (validateFunc[0]) {
                validateFunc = validateFunc[0].validate
                ControllerAndFunc.funs = ControllerAndFunc.funs.filter(item => !item.validate)
                var resultValidate = await validateFunc.call(controller)
                if (resultValidate && !resultValidate.success) {
                    ctx.body = {data: resultValidate.message, code: 501} || {data: "验证错误", code: 501}
                    ctx.status = 500
                    return false
                }
            }

            for (let i = 0; i < ControllerAndFunc.funs.length; i++) {
                var func = ControllerAndFunc.funs[i]
                try {
                    var _result = await func.call(controller)//把实例化对象注入 修改this
                    if (_result) {
                        result = _result
                    }
                } catch (e) {
                    error = e
                    console.error(e)
                }
            }
        }


        if (!ControllerAndFunc) {
            return ctx.throw(404)
        }
        if (error) {
            ctx.status = 500
            ctx.body = {data: error, code: 500}
        }
        if (ControllerAndFunc && !ctx.body) {
            ctx.body = {data: result}
        }


    }
}
